﻿/**
* Manager类的基类
*/
Ext.AbstractManager = Ext.extend(Object, {
    typeName: 'type',

    //构造函数
    constructor: function (config) {
        Ext.apply(this, config || {});//将配置信息传递给生成的对象

        this.all = new Ext.util.HashMap();//包含注册的对象

        this.types = {};//包含注册的类
    },

    //根据id获取注册对象
    get: function (id) {
        return this.all.get(id);//根据id键获得值
    },

    //注册一个对象，item就是要注册的对象，对象必须有id属性
    register: function (item) {
        this.all.add(item);//增加一个键值对：[item.id, item]
    },

    //注销一个对象
    unregister: function (item) {
        this.all.remove(item); //从哈希表中移除一个元素，参数代表元素的值
    },

    //注册一个类，type是类的类型，cls是类
    registerType: function (type, cls) {
        this.types[type] = cls;//types对象：{ type值: cls对象 }
        cls[this.typeName] = type;//cls对象：{ "type": type值 }
    },

    //判断指定类型的类是否已经注册
    isRegistered: function (type) {
        return this.types[type] !== undefined; //this.types对象中存在“type值”的属性，则返回true，否则返回false
    },

    //创建并返回一个指定类型的类的实例，类型信息在config中定义
    create: function (config, defaultType) {//config：配置对象；defaultType：如果在配置对象里没有找到类型，这默认用defaultType
        var type = config[this.typeName] || config.type || defaultType,
            Constructor = this.types[type];

        if (Constructor == undefined) {
            throw new Error(Ext.util.Format.format("The '{0}' type has not been registered with this manager", type));
        }

        return new Constructor(config);
    },

    //注册一个函数，该函数在指定id的对象被注册时调用一次。
    //id：组件id
    //fn：回调函数
    //scope：函数执行的作用域，默认为注册的组件
    onAvailable: function (id, fn, scope) {
        var all = this.all;

        all.on("add", function (index, o) {
            if (o.id == id) {
                fn.call(scope || o, o);
                all.un("add", fn, scope);
            }
        });
    },

    //遍历所以已注册的对象，且每遍历到一个对象时调用一次fn方法
    each: function (fn, scope) {
        this.all.each(fn, scope || this); //遍历哈希表，每遍历到一个元素就执行一次fn函数
    },

    //返回注册对象的数量
    getCount: function () {
        return this.all.getCount();//返回哈希表中元素的数目
    }
});

